package com.hhu.wangzb.common.entity.filter;

import com.alibaba.fastjson.JSON;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 实体过滤器
 */
@Component
public class EntityFilter {

    // 过滤器链
    private final List<Filter> filterChain = new ArrayList<>();

    public EntityFilter() {

        filterChain.add(new OmitFilter());
        filterChain.add(new FormatFilter());
        filterChain.add(new RenameFilter());

        // 优先级排序
        filterChain.sort((o1, o2) -> o2.getPriority() - o1.getPriority());
    }

    /**
     * 过滤实体类
     * @param entity
     * @param filterParam
     * @return
     */
    public Object filterEntity(Object entity, String filterParam) {
        if (filterParam == null) return entity;

        Map<String, Object> entityMap = transToMap(entity);

        FilterEntity filterEntity = JSON.parseObject(filterParam, FilterEntity.class);

        return doFilter(entityMap, filterEntity);
    }

    /**
     * 过滤实体类列表
     * @param entities
     * @param filterParam
     * @return
     */
    public List<?> filterList(List<?> entities, String filterParam) {
        if (filterParam == null) return entities;

        FilterEntity filterEntity = JSON.parseObject(filterParam, FilterEntity.class);

        List<Object> results = new ArrayList<>();

        for (Object o : entities) {
            Map<String, Object> entityMap = transToMap(o);
            results.add(doFilter(entityMap, filterEntity));
        }

        return results;
    }

    /**
     * 执行过滤器链
     * @param entityMap
     * @param filterEntity
     * @return 过滤结果
     */
    private Object doFilter(Map<String, Object> entityMap, FilterEntity filterEntity) {

        for (Filter filter : filterChain) {
            entityMap = filter.doFilter(entityMap, filterEntity);
        }

        return entityMap;
    }

    /**
     * 使用反射将实体类转化为map
     * @param entity 实体类
     * @return 实体类对应的map
     */
    private Map<String, Object> transToMap(Object entity) {
        // link有序
        Map<String, Object> entityMap = new LinkedHashMap<>();

        Class<?> entityClass = entity.getClass();

        Field[] fields = entityClass.getDeclaredFields();

        for (Field field : fields) {
            // 私有可访问
            field.setAccessible(true);

            try {
                entityMap.put(field.getName(), field.get(entity));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

        return entityMap;
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
        System.out.println(URLEncoder.encode("{\"omit\": [\"capacity\",\"type\",\"mode\"],\"rename\": {\"id\": \"标识\",\"comment\": \"备注\"}}","utf-8"));
    }

}
